package com.googlecode.allinclusive.tools.srcgen.generator;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.googlecode.allinclusive.tools.srcgen.database.TableDefinition;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;

public class FreeMarkerGenerator implements Generator {
	
	private static final Log log = LogFactory.getLog(FreeMarkerGenerator.class);  
	
	private String templateDirectory;
	
	private String outputDirectory;
	
	private String templateFileName;
	
	private String javaFileName;
		
	private Map<String, Object> templateDatas;
	
	public Map<String, Object> create(TableDefinition tableDefinition) {
		if (templateDatas == null) {
			templateDatas = new HashMap<String, Object>();
		}
		templateDatas.put("model", tableDefinition);
		
		return templateDatas;
	}
	
	public void generate(List<TableDefinition> tableDefinitions) {
		OutputStreamWriter out = null;
		Configuration cfg = new Configuration();
		try {
			File outputDir = new File(outputDirectory);
			if (outputDir.exists()) {
				outputDir.delete();
				outputDir.mkdirs();
			} 
			
			cfg.setDirectoryForTemplateLoading(new File(templateDirectory));
			cfg.setObjectWrapper(new DefaultObjectWrapper());
			Template t = cfg.getTemplate(templateFileName);
			
			for (TableDefinition tableDefinition : tableDefinitions) {
				String generateFileName = javaFileName;
				generateFileName = generateFileName.replaceAll("\\$\\{javaClass\\}", (String) PropertyUtils.getProperty(tableDefinition, "javaClass"));
				generateFileName = generateFileName.replaceAll("\\$\\{tableName\\}", (String) PropertyUtils.getProperty(tableDefinition, "tableName"));
				File javaFile = new File(outputDirectory + generateFileName);
				if (javaFile.exists()) {
					javaFile.delete();
				}
				javaFile.createNewFile();
				out = new OutputStreamWriter(new FileOutputStream(javaFile), "UTF-8");
				t.process(create(tableDefinition), out);
			}
			
		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			if (out != null) { try { out.close(); } catch (IOException e) {} }
		}
	}

	public void setTemplateDirectory(String templateDirectory) {
		this.templateDirectory = templateDirectory;
	}

	public void setOutputDirectory(String outputDirectory) {
		this.outputDirectory = outputDirectory;
	}

	public void setTemplateFileName(String templateFileName) {
		this.templateFileName = templateFileName;
	}

	public void setTemplateDatas(Map<String, Object> templateDatas) {
		this.templateDatas = templateDatas;
	}

	public void setJavaFileName(String javaFileName) {
		this.javaFileName = javaFileName;
	}
}
